home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Unix / skey / misc / su / su.c < prev   
Encoding:
C/C++ Source or Header  |  1995-04-15  |  4.6 KB  |  220 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. char copyright[] =
  9. "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10.  All rights reserved.\n";
  11. #endif not lint
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)su.c    5.4 (Berkeley) 1/13/86";
  15. #endif not lint
  16.  
  17. #include <stdio.h>
  18. #include <pwd.h>
  19. #include <grp.h>
  20. #include <syslog.h>
  21. #include <sys/types.h>
  22. #include <sys/time.h>
  23. #include <sys/resource.h>
  24.  
  25. char    userbuf[16]    = "USER=";
  26. char    homebuf[128]    = "HOME=";
  27. char    shellbuf[128]    = "SHELL=";
  28. char    pathbuf[128]    = "PATH=:/usr/ucb:/bin:/usr/bin";
  29. char    *cleanenv[] = { userbuf, homebuf, shellbuf, pathbuf, 0, 0 };
  30. char    *user = "root";
  31. char    *shell = "/bin/sh";
  32. int    fulllogin;
  33. int    fastlogin;
  34.  
  35. extern char    **environ;
  36. struct    passwd *pwd;
  37. char    *crypt();
  38. char    *getpass();
  39. char    *getenvr();
  40. char    *getlogin();
  41.  
  42. #ifdef SOLARIS
  43. #define setpriority(x,y,z)      z
  44. #endif
  45.  
  46. main(argc,argv)
  47.     int argc;
  48.     char *argv[];
  49. {
  50.     char *password;
  51.     char buf[1000];
  52.     FILE *fp;
  53.     register char *p;
  54.         int stat;
  55.  
  56.     openlog("su", LOG_ODELAY, LOG_AUTH);
  57.  
  58. again:
  59.     if (argc > 1 && strcmp(argv[1], "-f") == 0) {
  60.         fastlogin++;
  61.         argc--, argv++;
  62.         goto again;
  63.     }
  64.     if (argc > 1 && strcmp(argv[1], "-") == 0) {
  65.         fulllogin++;
  66.         argc--, argv++;
  67.         goto again;
  68.     }
  69.     if (argc > 1 && argv[1][0] != '-') {
  70.         user = argv[1];
  71.         argc--, argv++;
  72.     }
  73.     if ((pwd = getpwuid(getuid())) == NULL) {
  74.         fprintf(stderr, "Who are you?\n");
  75.         exit(1);
  76.     }
  77.     strcpy(buf, pwd->pw_name);
  78.     if ((pwd = getpwnam(user)) == NULL) {
  79.         fprintf(stderr, "Unknown login: %s\n", user);
  80.         exit(1);
  81.     }
  82.     /*
  83.      * Only allow those in group zero to su to root.
  84.          */
  85.     if (pwd->pw_uid == 0) {
  86.         struct    group *gr;
  87.         int i;
  88.  
  89.         if ((gr = getgrgid(0)) != NULL) {
  90.             for (i = 0; gr->gr_mem[i] != NULL; i++)
  91.                 if (strcmp(buf, gr->gr_mem[i]) == 0)
  92.                     goto userok;
  93.             fprintf(stderr, "You do not have permission to su %s\n",
  94.                 user);
  95.             exit(1);
  96.         }
  97.     userok:
  98.         setpriority(PRIO_PROCESS, 0, -2);
  99.     }
  100.  
  101. #define Getlogin()  (((p = getlogin()) && *p) ? p : buf)
  102.  
  103. #ifdef SKEY
  104.         stat = skey_haskey (user);
  105.  
  106.         if (stat == 1) {
  107.            fprintf(stderr,"keysh: no entry for user %s.\n", user);
  108.            goto OLDPASSWDENTRY; 
  109.          }
  110.  
  111.         if (stat == -1) {
  112.            fprintf(stderr, "keysh: could not open key file.\n");
  113.            goto OLDPASSWDENTRY; 
  114.         }
  115.  
  116.         if (skey_authenticate (user) == -1) {
  117.             fprintf(stderr, "Sorry\n");
  118.                 if (pwd->pw_uid == 0) {
  119.                     syslog (LOG_CRIT, "BAD SU %s on %s",
  120.                           Getlogin(), ttyname(2));
  121.                 }
  122.             exit (-1);
  123.         }
  124.         goto ok;
  125.  
  126. OLDPASSWDENTRY:
  127. #endif
  128.  
  129.     if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
  130.         goto ok;
  131.     password = getpass("Password:");
  132.     if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
  133.         fprintf(stderr, "Sorry\n");
  134.         if (pwd->pw_uid == 0) {
  135.             syslog(LOG_CRIT, "BAD SU %s on %s",
  136.                     Getlogin(), ttyname(2));
  137.         }
  138.         exit(2);
  139.     }
  140. ok:
  141.     endpwent();
  142.     if (pwd->pw_uid == 0) {
  143.         syslog(LOG_NOTICE, "%s on %s", Getlogin(), ttyname(2));
  144.         closelog();
  145.     }
  146.     if (setgid(pwd->pw_gid) < 0) {
  147.         perror("su: setgid");
  148.         exit(3);
  149.     }
  150.     if (initgroups(user, pwd->pw_gid)) {
  151.         fprintf(stderr, "su: initgroups failed\n");
  152.         exit(4);
  153.     }
  154.     if (setuid(pwd->pw_uid) < 0) {
  155.         perror("su: setuid");
  156.         exit(5);
  157.     }
  158.     if (pwd->pw_shell && *pwd->pw_shell)
  159.         shell = pwd->pw_shell;
  160.     if (fulllogin) {
  161.         cleanenv[4] = getenvr("TERM");
  162.         environ = cleanenv;
  163.     }
  164.     if (strcmp(user, "root"))
  165.         setenv("USER", pwd->pw_name, userbuf);
  166.     setenv("SHELL", shell, shellbuf);
  167.     setenv("HOME", pwd->pw_dir, homebuf);
  168.     setpriority(PRIO_PROCESS, 0, 0);
  169.     if (fastlogin) {
  170.         *argv-- = "-f";
  171.         *argv = "su";
  172.     } else if (fulllogin) {
  173.         if (chdir(pwd->pw_dir) < 0) {
  174.             fprintf(stderr, "No directory\n");
  175.             exit(6);
  176.         }
  177.         *argv = "-su";
  178.     } else
  179.         *argv = "su";
  180.     execv(shell, argv);
  181.     fprintf(stderr, "No shell\n");
  182.     exit(7);
  183. }
  184.  
  185. setenv(ename, eval, buf)
  186.     char *ename, *eval, *buf;
  187. {
  188.     register char *cp, *dp;
  189.     register char **ep = environ;
  190.  
  191.     /*
  192.      * this assumes an environment variable "ename" already exists
  193.      */
  194.     while (dp = *ep++) {
  195.         for (cp = ename; *cp == *dp && *cp; cp++, dp++)
  196.             continue;
  197.         if (*cp == 0 && (*dp == '=' || *dp == 0)) {
  198.             strcat(buf, eval);
  199.             *--ep = buf;
  200.             return;
  201.         }
  202.     }
  203. }
  204.  
  205. char *
  206. getenvr(ename)
  207.     char *ename;
  208. {
  209.     register char *cp, *dp;
  210.     register char **ep = environ;
  211.  
  212.     while (dp = *ep++) {
  213.         for (cp = ename; *cp == *dp && *cp; cp++, dp++)
  214.             continue;
  215.         if (*cp == 0 && (*dp == '=' || *dp == 0))
  216.             return (*--ep);
  217.     }
  218.     return ((char *)0);
  219. }
  220.